﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using PortSet;
//using WindowsFormsApplication1;

namespace Simple_Terminal
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void settingsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("Menu item 'Settings'");
            // Make sure the port isn't already open
            if (serialPort1.IsOpen)
            {
                MessageBox.Show("The port must be closed before changing the settings.");
                return;
            }
            else
            {
                // creat an instance of the settings form
                PortSettings settings = new PortSettings();

                if (settings.ShowDialog() == DialogResult.OK)
                {
                    if (settings.selectedPort != "")
                    {
                        // set the serial port to the new settings
                        serialPort1.PortName = settings.selectedPort;
                        serialPort1.BaudRate = settings.selectedBaudrate;
                        serialPort1.DataBits = settings.selectedDataBits;
                        serialPort1.Parity = settings.selectedParity;
                        serialPort1.StopBits = settings.selectedStopBits;

                        // show the new settings in the form text line
                        showSettings();
                    }
                    else
                    {
                        MessageBox.Show("Error: Settings form returned with no COM port selected.");
                        return; // bail out
                    }

                }
                else
                {
                    MessageBox.Show("Error: buttonSetup_Click - Settings dialog box did not return Okay.");
                    return; // bail out
                }

                // open the port
                try
                {
                    serialPort1.Close();
                    serialPort1.Open();
                    menuStrip1.Items[1].Text = "Close Port";

                    showSettings();
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Error - setupToolStripMenuItem_Click Exception: " + ex);
                }
            }
        }

        // show the settings in the form text line
        private void showSettings()
        {
            this.Text = "Smiley Micros - " +
                serialPort1.PortName + " " +
                serialPort1.BaudRate.ToString() + "," +
                serialPort1.Parity + "," +
                serialPort1.DataBits.ToString() + "," +
                serialPort1.StopBits;
            if (serialPort1.IsOpen)
            {
                this.Text += " - Port is open";
            }
            else
            {
                this.Text += " - Port is closed";
            }
        }

        // toggle the port state
        private void openPortToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                if (serialPort1.IsOpen)
                {
                    serialPort1.Close();
                    menuStrip1.Items[1].Text = "Open Port";
                }
                else
                {
                    serialPort1.Open();
                    menuStrip1.Items[1].Text = "Close Port";
                }

                showSettings();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Error - openPortToolStripMenuItem_Click Exception: " + ex);
            }
        }

        //private void openPortToolStripMenuItem_Click(object sender, EventArgs e)
        //{
        //    MessageBox.Show("Menu item 'Open Port'");
        //}

        private void clearToolStripMenuItem_Click(object sender, EventArgs e)
        {
            //MessageBox.Show("Menu item 'Clear'");
            richTextBox1.Text = "";
            richTextBox2.Text = "";
        }

        private void richTextBox1_TextChanged(object sender, EventArgs e)
        {

        }

        #region transmit functions

        private void richTextBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            sendChar(e.KeyChar);
        }

        private void sendChar(char c)
        {
            char[] data = new Char[1];
            data[0] = c;
            try
            {
                serialPort1.Write(data, 0, 1);
            }
            catch
            {
                MessageBox.Show("Error: sendByte - failed to send.\nIs the port open?");
            }
        }
        #endregion

        #region receive functions

        // we want to have the serial port thread report back data received, but to display
        // that data we must create a delegate function to show the data in the richTextBox

        // define the delegate 
        public delegate void SetText();
        // define an instance of the delegate
        SetText setText;

        // create a string that will be loaded with the data received from the port
        public string str = "";

        // note that this function runs in a separate thread and thus we must use a delegate in order
        // to display the results in the richTextBox.
        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            // instantiate the delegate to be invoked by this thread
            setText = new SetText(mySetText);

            // load the data into the string
            try
            {
                str = serialPort1.ReadExisting();
            }
            catch (System.Exception ex)
            {
                MessageBox.Show("Error - port_DataReceived Exception: " + ex);
            }

            // invoke the delegate in the MainForm thread
            this.Invoke(setText);
        }

        // create the instance of the delegate to be used to write the received data to the richTextBox
        public void mySetText()
        {
            // show the text
            richTextBox2.Text += str.ToString();

            moveCaretToEnd();
        }

        // This rigaramole is needed to keep the last received item displayed
        // it kind of flickers and should be fixed
        private void richTextBoxReceive_TextChanged(object sender, System.EventArgs e)
        {
            moveCaretToEnd();
        }

        private void moveCaretToEnd()
        {
            richTextBox1.SelectionStart = richTextBox1.Text.Length;
            richTextBox1.SelectionLength = 0;
            richTextBox1.ScrollToCaret();
        }

        #endregion


    }
}
